/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package pl.edu.amu.wmi.kino.visualjavafx.model.api;

/**
 *
 * @author psychollek
 */
public class ModelChangeEvent {
    private String desc;
    private Object[] rmChildren;
    private Object[] newChildren;
    private Object modified;
    private Object[] who;

    private ModelChangeEvent(String desc,Object[] who,Object modified,Object[] newChildren,Object[] rmChildren ){
        this.desc = desc;
        this.who = who;
        this.modified = modified;
        this.newChildren = newChildren;
        this.rmChildren = rmChildren;
    }

    /**
     * returns array of invoking objects. - getWho[0] is orginal object who made
     * change, getWho[getWho.lenght-1] is last passing object.
     * @return array of invoking objects.
     */
    public Object[] getWho(){
        return who;
    };

    /**
     * returns the object that was modified. for example if Circle had it's Color
     * changed - this shall return this Circle.
     * @return the object that was modified.
     */
    public Object getModifiedElement(){
        return modified;
    }

    /**
     * @return children added to the modified object or null if none where.
     */
    public Object[] getNewChildren(){
        return newChildren;
    }

    /**
     * @return children removed from the modified object null if none.
     */
    public Object[] getRemovedChildren(){
        return rmChildren;
    }

    /**
     *
     * @return description of the change.
     */
    public String getDescription(){
        return desc;
    }

    /**
     * use this to pass an event - do not pass unmodified one !
     * @param evt - passed event
     * @param who - usually "this"
     * @return event to pass
     */
    public static ModelChangeEvent passEvent(ModelChangeEvent evt, Object who){
        Object[] nWho = new Object[evt.who.length+1];
        int i = 0;
        for (i = 0; i < evt.who.length; i++) {
            nWho[i] = evt.who[i];
        }
        nWho[i] = who;
        return new ModelChangeEvent(evt.desc,evt.who,evt.modified,evt.newChildren,evt.rmChildren);
    }

    /**
     * use this when many chidren are added
     * @param who - usually "this"
     * @param modified - parent of children
     * @param children - array of children
     * @return event to pass
     */
    public static ModelChangeEvent newChildren(Object who,Object modified,Object[] children){
        return new ModelChangeEvent("childrenAdded",new Object[] {who},modified,children,null);
    }

    /**
     * use this when one chid is added
     * @param who - usually "this"
     * @param modified - parent of child
     * @param children - child, can't be arrray !
     * @return event to pass
     */
    public static ModelChangeEvent newChildren(Object who,Object modified,Object children){
        return new ModelChangeEvent("childrenAdded",new Object[] {who},modified,new Object[] {children},null);
    }

    /**
     * use this when many chidren are removed
     * @param who - usually "this"
     * @param modified - parent of children
     * @param children - array of children
     * @return event to pass
     */
    public static ModelChangeEvent childrenRemoved(Object who,Object modified,Object[] children){
        return new ModelChangeEvent("childrenRemoved",new Object[] {who},modified,null,children);
    }

    /**
     * use this when one chid is removed
     * @param who - usually "this"
     * @param modified - parent of children
     * @param children - array of children
     * @return event to pass
     */
    public static ModelChangeEvent childrenRemoved(Object who,Object modified,Object children){
        return new ModelChangeEvent("childrenRemoved",new Object[] {who},modified,null,new Object[] {children});
    }

    /**
     * use this when property of element is modified
     * @param who - usually "this"
     * @param modified - owner of changed property
     * @param propertyName - the name of property
     * @return event to pass
     */
    public static ModelChangeEvent propertyChanged(Object who,Object modified,String propertyName){
        return new ModelChangeEvent("propertyChanged: "+propertyName,new Object[] {who},modified,null,null);
    }

    /**
     * this shall not have any effect
     * @param who - usually "this"
     * @return ModelChangeEvent with all properties except for who == null
     */
    public static ModelChangeEvent emptyEvent(Object who){
        return new ModelChangeEvent(null,new Object[] {who},null,null,null);
    }



}
